using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Outpatient.Doman.Smart;
using Outpatient.Doman.SmartClinic;
using Outpatient.ErrorCode;
using Outpatient.Infrastructure;
using OutpatientApi.DTO;
using OutpatientApi.Methodimplementation.IServices;
using System.ComponentModel.DataAnnotations;

namespace OutpatientApi.Methodimplementation.Services
{
    /// <summary>
    /// 病人挂号服务实现类
    /// </summary>
    public class PatientRegistrationService : IPatientRegistrationService
    {
        private readonly EFDbContext _context;
        private readonly ILogger<PatientRegistrationService> _logger;
        private readonly IBaseRepository<DoctorInfo> doctorInfo;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="logger">日志记录器</param>
        public PatientRegistrationService(EFDbContext context, ILogger<PatientRegistrationService> logger,IBaseRepository<DoctorInfo> doctorInfo)
        {
            _context = context;
            _logger = logger;
            this.doctorInfo = doctorInfo;
        }

        /// <summary>
        /// 添加病人挂号
        /// </summary>
        /// <param name="addDto">添加病人挂号参数</param>
        /// <returns>添加结果</returns>
        public async Task<ApiResult<int>> AddPatientRegistrationAsync(AddPatientRegistrationDto addDto)
        {
            try
            {
                // 记录添加开始日志
                _logger.LogInformation("开始添加病人挂号，患者姓名：{PatientName}，挂号单号：{RegisterNo}", 
                    addDto.PatientName, addDto.RegisterNo);

                // 参数验证
                var validationResults = new List<ValidationResult>();
                var validationContext = new ValidationContext(addDto);
                if (!Validator.TryValidateObject(addDto, validationContext, validationResults, true))
                {
                    var errorMessage = string.Join("; ", validationResults.Select(v => v.ErrorMessage));
                    _logger.LogWarning("添加病人挂号失败：参数验证失败 - {ErrorMessage}", errorMessage);
                    return new ApiResult<int> { msg = errorMessage };
                }

                // 检查挂号单号是否已存在
                var existingRegistration = await _context.Patient_Registrations
                    .FirstOrDefaultAsync(r => r.RegisterNo == addDto.RegisterNo && !r.IsDelete);

                if (existingRegistration != null)
                {
                    _logger.LogWarning("添加病人挂号失败：挂号单号已存在，挂号单号：{RegisterNo}", addDto.RegisterNo);
                    return new ApiResult<int> { msg = "挂号单号已存在" };
                }

                // 验证挂号类别是否存在
                var registerType = await _context.Number_Categories
                    .FirstOrDefaultAsync(rt => rt.Number_categoryId == addDto.RegisterTypeId && !rt.IsDelete);

                if (registerType == null)
                {
                    _logger.LogWarning("添加病人挂号失败：挂号类别不存在，挂号类别ID：{RegisterTypeId}", addDto.RegisterTypeId);
                    return new ApiResult<int> { msg = "挂号类别不存在" };
                }

                // 验证医生是否存在
                var doctor = await _context.DoctorInfo
                    .FirstOrDefaultAsync(d => d.DoctorId == addDto.DoctorId && !d.IsDeleted);

                if (doctor == null)
                {
                    _logger.LogWarning("添加病人挂号失败：医生不存在，医生ID：{DoctorId}", addDto.DoctorId);
                    return new ApiResult<int> { msg = "医生不存在" };
                }

                // 验证科室是否存在
                var department = await _context.DepartmentInfos
                    .FirstOrDefaultAsync(d => d.DepartmentId == addDto.DepartmentId && !d.IsDelete);

                if (department == null)
                {
                    _logger.LogWarning("添加病人挂号失败：科室不存在，科室ID：{DepartmentId}", addDto.DepartmentId);
                    return new ApiResult<int> { msg = "科室不存在" };
                }

                // 创建新的病人挂号记录
                var patientRegistration = new Patient_registration
                {
                    RegisterNo = addDto.RegisterNo,
                    RegisterTypeId = addDto.RegisterTypeId,
                    DoctorId = addDto.DoctorId,
                    CardNo = addDto.CardNo,
                    DepartmentId = addDto.DepartmentId,
                    RegisterFee = addDto.RegisterFee,
                    OtherFee = addDto.OtherFee,
                    RegisterDate = addDto.RegisterDate,
                    VisitDate = addDto.VisitDate,
                    PatientName = addDto.PatientName,
                    IDNumber = addDto.IDNumber,
                    Age = addDto.Age,
                    Address = addDto.Address,
                    PhoneNumber = addDto.PhoneNumber,
                    Ethnicity = addDto.Ethnicity,
                    EducationLevel = addDto.EducationLevel,
                    Occupation = addDto.Occupation,
                    PostalCode = addDto.PostalCode,
                    MaritalStatus = addDto.MaritalStatus,
                    Gender = addDto.Gender,
                    DateOfBirth = addDto.DateOfBirth,
                    IsDelete = false
                };

                // 添加到数据库
                _context.Patient_Registrations.Add(patientRegistration);
                await _context.SaveChangesAsync();

                // 记录添加成功日志
                _logger.LogInformation("病人挂号添加成功，挂号ID：{PatientRegistrationId}，患者姓名：{PatientName}，挂号单号：{RegisterNo}", 
                    patientRegistration.Patient_registrationId, addDto.PatientName, addDto.RegisterNo);

                var apiResult = new ApiResult<int>();
                apiResult.success(patientRegistration.Patient_registrationId, "病人挂号添加成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "添加病人挂号时发生异常，患者姓名：{PatientName}，挂号单号：{RegisterNo}", 
                    addDto.PatientName, addDto.RegisterNo);
                return new ApiResult<int> { msg = "添加病人挂号时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 获取所有号类数据
        /// </summary>
        /// <returns>号类数据列表</returns>
        public async Task<ApiResult<List<NumberCategoryDto>>> GetAllNumberCategoriesAsync()
        {
            try
            {
                // 记录查询开始日志
                _logger.LogInformation("开始查询所有号类数据");

                // 查询所有未删除的号类数据
                var numberCategories = await _context.Number_Categories
                    .Where(nc => !nc.IsDelete)
                    .Select(nc => new NumberCategoryDto
                    {
                        Number_categoryId = nc.Number_categoryId,
                        Number_categoryName = nc.Number_categoryName
                    })
                    .ToListAsync();

                // 记录查询成功日志
                _logger.LogInformation("查询号类数据成功，共找到 {Count} 条记录", numberCategories.Count);

                var apiResult = new ApiResult<List<NumberCategoryDto>>();
                apiResult.success(numberCategories, "查询号类数据成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "查询号类数据时发生异常");
                return new ApiResult<List<NumberCategoryDto>> { msg = "查询号类数据时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 获取所有科室信息
        /// </summary>
        /// <returns>科室信息列表</returns>
        public async Task<ApiResult<List<DepartmentInfoDto>>> GetAllDepartmentInfosAsync()
        {
            try
            {
                // 记录查询开始日志
                _logger.LogInformation("开始查询所有科室信息");

                // 查询所有未删除的科室信息
                var departmentInfos = await _context.DepartmentInfos
                    .Where(d => !d.IsDelete)
                    .Select(d => new DepartmentInfoDto
                    {
                        DepartmentId = d.DepartmentId,
                        DepartmentName = d.DepartmentName
                    })
                    .ToListAsync();

                // 记录查询成功日志
                _logger.LogInformation("查询科室信息成功，共找到 {Count} 条记录", departmentInfos.Count);

                var apiResult = new ApiResult<List<DepartmentInfoDto>>();
                apiResult.success(departmentInfos, "查询科室信息成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "查询科室信息时发生异常");
                return new ApiResult<List<DepartmentInfoDto>> { msg = "查询科室信息时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 获取所有医生信息
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<List<GetDepartmentInfoDto>>> GetDepartmentInfo()
        {
            try
            {
                var res = new ApiResult<List<GetDepartmentInfoDto>>();

                var info = doctorInfo.Getlist().Where(x => x.IsDeleted.Equals(false)).Select(x => new GetDepartmentInfoDto()
                {
                    DoctorId=x.DoctorId,
                    Name=x.Name
                }).ToList();

                res.success(info, "查找医生信息成功");
                return res;

            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 添加医疗卡办理
        /// </summary>
        /// <param name="addDto">添加医疗卡办理参数</param>
        /// <returns>添加结果</returns>
        public async Task<ApiResult<int>> AddMedicalCardRegistrationAsync(AddMedicalCardRegistrationDto addDto)
        {
            try
            {
                // 记录添加开始日志
                _logger.LogInformation("开始添加医疗卡办理，用户姓名：{Name}，身份证号：{IDNumber}", 
                    addDto.Name, addDto.IDNumber);

                // 参数验证
                var validationResults = new List<ValidationResult>();
                var validationContext = new ValidationContext(addDto);
                if (!Validator.TryValidateObject(addDto, validationContext, validationResults, true))
                {
                    var errorMessage = string.Join("; ", validationResults.Select(v => v.ErrorMessage));
                    _logger.LogWarning("添加医疗卡办理失败：参数验证失败 - {ErrorMessage}", errorMessage);
                    return new ApiResult<int> { msg = errorMessage };
                }

                // 检查身份证号是否已存在
                var existingCard = await _context.MedicalCardRegistrations
                    .FirstOrDefaultAsync(r => r.IDNumber == addDto.IDNumber);

                if (existingCard != null)
                {
                    _logger.LogWarning("添加医疗卡办理失败：身份证号已存在，身份证号：{IDNumber}", addDto.IDNumber);
                    return new ApiResult<int> { msg = "身份证号已存在，不能重复办理医疗卡" };
                }

                // 验证民族是否存在
                var ethnicity = await _context.Ethnic_Groups
                    .FirstOrDefaultAsync(e => e.Ethnic_groupId == addDto.Ethnicity);

                if (ethnicity == null)
                {
                    _logger.LogWarning("添加医疗卡办理失败：民族不存在，民族ID：{Ethnicity}", addDto.Ethnicity);
                    return new ApiResult<int> { msg = "民族不存在" };
                }

                // 验证文化程度是否存在
                var culture = await _context.Cultures
                    .FirstOrDefaultAsync(c => c.CultureId == addDto.EducationLevel);

                if (culture == null)
                {
                    _logger.LogWarning("添加医疗卡办理失败：文化程度不存在，文化程度ID：{EducationLevel}", addDto.EducationLevel);
                    return new ApiResult<int> { msg = "文化程度不存在" };
                }

                // 验证职业是否存在
                var occupation = await _context.Occupations
                    .FirstOrDefaultAsync(o => o.OccupationId == addDto.OccupationId);

                if (occupation == null)
                {
                    _logger.LogWarning("添加医疗卡办理失败：职业不存在，职业ID：{OccupationId}", addDto.OccupationId);
                    return new ApiResult<int> { msg = "职业不存在" };
                }

                // 自动生成卡号 - 从10001开始
                var lastCard = await _context.MedicalCardRegistrations
                    .OrderByDescending(c => c.Card_number)
                    .FirstOrDefaultAsync();

                string newCardNumber;
                if (lastCard == null)
                {
                    newCardNumber = "10001";
                }
                else
                {
                    if (int.TryParse(lastCard.Card_number, out int lastNumber))
                    {
                        newCardNumber = (lastNumber + 1).ToString();
                    }
                    else
                    {
                        newCardNumber = "10001";
                    }
                }

                // 创建新的医疗卡注册记录
                var medicalCardRegistration = new MedicalCardRegistration
                {
                    Card_number = newCardNumber,
                    Name = addDto.Name,
                    Gender = addDto.Gender,
                    Age = addDto.Age,
                    Address = addDto.Address,
                    Phone = addDto.Phone,
                    Ethnicity = addDto.Ethnicity,
                    EducationLevel = addDto.EducationLevel,
                    OccupationId = addDto.OccupationId,
                    PostalCode = addDto.PostalCode,
                    MaritalStatus = addDto.MaritalStatus,
                    DateOfBirth = addDto.DateOfBirth,
                    IDNumber = addDto.IDNumber,
                    IsDelete = false
                };

                // 添加到数据库
                _context.MedicalCardRegistrations.Add(medicalCardRegistration);
                await _context.SaveChangesAsync();

                // 记录添加成功日志
                _logger.LogInformation("医疗卡办理添加成功，医疗卡ID：{MedicalCardRegistrationId}，用户姓名：{Name}，卡号：{CardNumber}，身份证号：{IDNumber}", 
                    medicalCardRegistration.MedicalCardRegistrationId, addDto.Name, newCardNumber, addDto.IDNumber);

                var apiResult = new ApiResult<int>();
                apiResult.success(medicalCardRegistration.MedicalCardRegistrationId, "医疗卡办理添加成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "添加医疗卡办理时发生异常，用户姓名：{Name}，身份证号：{IDNumber}", 
                    addDto.Name, addDto.IDNumber);
                return new ApiResult<int> { msg = "添加医疗卡办理时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 获取所有民族数据
        /// </summary>
        /// <returns>民族数据列表</returns>
        public async Task<ApiResult<List<EthnicGroupDto>>> GetAllEthnicGroupsAsync()
        {
            try
            {
                // 记录查询开始日志
                _logger.LogInformation("开始查询所有民族数据");

                // 查询所有民族数据
                var ethnicGroups = await _context.Ethnic_Groups
                    .Select(eg => new EthnicGroupDto
                    {
                        Ethnic_groupId = eg.Ethnic_groupId,
                        Ethnic_groupName = eg.Ethnic_groupName
                    })
                    .ToListAsync();

                // 记录查询成功日志
                _logger.LogInformation("查询民族数据成功，共找到 {Count} 条记录", ethnicGroups.Count);

                var apiResult = new ApiResult<List<EthnicGroupDto>>();
                apiResult.success(ethnicGroups, "查询民族数据成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "查询民族数据时发生异常");
                return new ApiResult<List<EthnicGroupDto>> { msg = "查询民族数据时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 获取所有文化程度数据
        /// </summary>
        /// <returns>文化程度数据列表</returns>
        public async Task<ApiResult<List<CultureDto>>> GetAllCulturesAsync()
        {
            try
            {
                // 记录查询开始日志
                _logger.LogInformation("开始查询所有文化程度数据");

                // 查询所有文化程度数据
                var cultures = await _context.Cultures
                    .Select(c => new CultureDto
                    {
                        CultureId = c.CultureId,
                        CultureName = c.CultureName
                    })
                    .ToListAsync();

                // 记录查询成功日志
                _logger.LogInformation("查询文化程度数据成功，共找到 {Count} 条记录", cultures.Count);

                var apiResult = new ApiResult<List<CultureDto>>();
                apiResult.success(cultures, "查询文化程度数据成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "查询文化程度数据时发生异常");
                return new ApiResult<List<CultureDto>> { msg = "查询文化程度数据时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 获取所有职业数据
        /// </summary>
        /// <returns>职业数据列表</returns>
        public async Task<ApiResult<List<OccupationDto>>> GetAllOccupationsAsync()
        {
            try
            {
                // 记录查询开始日志
                _logger.LogInformation("开始查询所有职业数据");

                // 查询所有职业数据
                var occupations = await _context.Occupations
                    .Select(o => new OccupationDto
                    {
                        OccupationId = o.OccupationId,
                        OccupationName = o.OccupationName
                    })
                    .ToListAsync();

                // 记录查询成功日志
                _logger.LogInformation("查询职业数据成功，共找到 {Count} 条记录", occupations.Count);

                var apiResult = new ApiResult<List<OccupationDto>>();
                apiResult.success(occupations, "查询职业数据成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "查询职业数据时发生异常");
                return new ApiResult<List<OccupationDto>> { msg = "查询职业数据时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 查询病人挂号信息
        /// </summary>
        /// <param name="patientName">患者姓名（可选）</param>
        /// <param name="registerNo">挂号单号（可选）</param>
        /// <param name="idNumber">身份证号（可选）</param>
        /// <returns>病人挂号信息列表</returns>
        public async Task<ApiResult<List<GetPatientRegistrationDto>>> GetPatientRegistrationsAsync(string? patientName = null, string? registerNo = null, string? idNumber = null)
        {
            try
            {
                // 记录查询开始日志
                _logger.LogInformation("开始查询病人挂号信息，患者姓名：{PatientName}，挂号单号：{RegisterNo}，身份证号：{IDNumber}", 
                    patientName, registerNo, idNumber);

                // 构建查询条件
                var query = _context.Patient_Registrations
                    .Include(pr => pr.RegisterType)
                    .Include(pr => pr.Doctor)
                    .Include(pr => pr.Department)
                    .AsQueryable();

                // 根据患者姓名筛选
                if (!string.IsNullOrWhiteSpace(patientName))
                {
                    query = query.Where(pr => pr.PatientName.Contains(patientName));
                }

                // 根据挂号单号筛选（精确匹配）
                if (!string.IsNullOrWhiteSpace(registerNo))
                {
                    query = query.Where(pr => pr.RegisterNo == registerNo);
                }

                // 根据身份证号筛选
                if (!string.IsNullOrWhiteSpace(idNumber))
                {
                    query = query.Where(pr => pr.IDNumber.Contains(idNumber));
                }

                // 执行查询并映射到DTO
                var patientRegistrations = await query
                    .Select(pr => new GetPatientRegistrationDto
                    {
                        Patient_registrationId = pr.Patient_registrationId,
                        RegisterNo = pr.RegisterNo,
                        RegisterTypeId = pr.RegisterTypeId,
                        RegisterTypeName = pr.RegisterType != null ? pr.RegisterType.Number_categoryName : string.Empty,
                        DoctorId = pr.DoctorId,
                        DoctorName = pr.Doctor != null ? pr.Doctor.Name : string.Empty,
                        CardNo = pr.CardNo,
                        DepartmentId = pr.DepartmentId,
                        DepartmentName = pr.Department != null ? pr.Department.DepartmentName : string.Empty,
                        RegisterFee = pr.RegisterFee,
                        OtherFee = pr.OtherFee,
                        RegisterDate = pr.RegisterDate,
                        VisitDate = pr.VisitDate,
                        PatientName = pr.PatientName,
                        IDNumber = pr.IDNumber,
                        Age = pr.Age,
                        Address = pr.Address,
                        PhoneNumber = pr.PhoneNumber,
                        Ethnicity = pr.Ethnicity,
                        EducationLevel = pr.EducationLevel,
                        Occupation = pr.Occupation,
                        PostalCode = pr.PostalCode,
                        MaritalStatus = pr.MaritalStatus,
                        Gender = pr.Gender,
                        DateOfBirth = pr.DateOfBirth
                    })
                    .ToListAsync();

                // 记录查询成功日志
                _logger.LogInformation("查询病人挂号信息成功，共找到 {Count} 条记录", patientRegistrations.Count);

                var apiResult = new ApiResult<List<GetPatientRegistrationDto>>();
                apiResult.success(patientRegistrations, "查询病人挂号信息成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "查询病人挂号信息时发生异常，患者姓名：{PatientName}，挂号单号：{RegisterNo}，身份证号：{IDNumber}", 
                    patientName, registerNo, idNumber);
                return new ApiResult<List<GetPatientRegistrationDto>> { msg = "查询病人挂号信息时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 查询消费明细信息（多表连查）
        /// </summary>
        /// <param name="patientName">患者姓名（可选）</param>
        /// <param name="registerNo">挂号单号（可选）</param>
        /// <param name="drugName">药品名称（可选）</param>
        /// <param name="patientRegistrationId">病人挂号ID（可选）</param>
        /// <returns>消费明细信息列表</returns>
        public async Task<ApiResult<List<GetConsumptionDetailsDto>>> GetConsumptionDetailsAsync(string? patientName = null, string? registerNo = null, string? drugName = null, int? patientRegistrationId = null)
        {
            try
            {
                // 记录查询开始日志
                _logger.LogInformation("开始查询消费明细信息，患者姓名：{PatientName}，挂号单号：{RegisterNo}，药品名称：{DrugName}，病人挂号ID：{PatientRegistrationId}", 
                    patientName, registerNo, drugName, patientRegistrationId);

                // 构建多表连查查询（左连接）
                var query = _context.Consumption_Details
                    .Include(cd => cd.PatientRegistration)
                        .ThenInclude(pr => pr.Department)
                    .Include(cd => cd.PatientRegistration)
                        .ThenInclude(pr => pr.Doctor)
                    .Include(cd => cd.PatientRegistration)
                        .ThenInclude(pr => pr.RegisterType)
                    .AsQueryable();

                // 根据病人挂号ID筛选
                if (patientRegistrationId.HasValue)
                {
                    query = query.Where(cd => cd.Patient_registrationId == patientRegistrationId.Value);
                }

                // 根据药品名称筛选
                if (!string.IsNullOrWhiteSpace(drugName))
                {
                    query = query.Where(cd => cd.DrugName.Contains(drugName));
                }

                // 根据患者姓名筛选（通过关联的病人挂号表，左连接安全）
                if (!string.IsNullOrWhiteSpace(patientName))
                {
                    query = query.Where(cd => cd.PatientRegistration != null && cd.PatientRegistration.PatientName.Contains(patientName));
                }

                // 根据挂号单号筛选（通过关联的病人挂号表，精确匹配，左连接安全）
                if (!string.IsNullOrWhiteSpace(registerNo))
                {
                    query = query.Where(cd => cd.PatientRegistration != null && cd.PatientRegistration.RegisterNo == registerNo);
                }

                // 执行查询并映射到DTO（左连接确保数据完整性）
                var consumptionDetails = await query
                    .Select(cd => new GetConsumptionDetailsDto
                    {
                        Consumption_detailsId = cd.Consumption_detailsId,
                        Patient_registrationId = cd.Patient_registrationId,
                        DrugName = cd.DrugName,
                        UnitPrice = cd.UnitPrice,
                        Quantity = cd.Quantity,
                        SubTotal = cd.UnitPrice * cd.Quantity, // 计算小计金额
                        RegisterNo = cd.PatientRegistration != null ? cd.PatientRegistration.RegisterNo : string.Empty,
                        PatientName = cd.PatientRegistration != null ? cd.PatientRegistration.PatientName : string.Empty,
                        IDNumber = cd.PatientRegistration != null ? cd.PatientRegistration.IDNumber : string.Empty,
                        RegisterDate = cd.PatientRegistration != null ? cd.PatientRegistration.RegisterDate : DateTime.MinValue,
                        VisitDate = cd.PatientRegistration != null ? cd.PatientRegistration.VisitDate : DateTime.MinValue,
                        RegisterFee = cd.PatientRegistration != null ? cd.PatientRegistration.RegisterFee : 0,
                        OtherFee = cd.PatientRegistration != null ? cd.PatientRegistration.OtherFee : 0,
                        DepartmentName = cd.PatientRegistration != null && cd.PatientRegistration.Department != null ? cd.PatientRegistration.Department.DepartmentName : string.Empty,
                        DoctorName = cd.PatientRegistration != null && cd.PatientRegistration.Doctor != null ? cd.PatientRegistration.Doctor.Name : string.Empty,
                        RegisterTypeName = cd.PatientRegistration != null && cd.PatientRegistration.RegisterType != null ? cd.PatientRegistration.RegisterType.Number_categoryName : string.Empty,
                        Age = cd.PatientRegistration != null ? cd.PatientRegistration.Age : 0,
                        Gender = cd.PatientRegistration != null ? cd.PatientRegistration.Gender : false,
                        PhoneNumber = cd.PatientRegistration != null ? cd.PatientRegistration.PhoneNumber : string.Empty,
                        Address = cd.PatientRegistration != null ? cd.PatientRegistration.Address : string.Empty,
                        Ethnicity = cd.PatientRegistration != null ? cd.PatientRegistration.Ethnicity : string.Empty,
                        EducationLevel = cd.PatientRegistration != null ? cd.PatientRegistration.EducationLevel : string.Empty,
                        Occupation = cd.PatientRegistration != null ? cd.PatientRegistration.Occupation : string.Empty,
                        PostalCode = cd.PatientRegistration != null ? cd.PatientRegistration.PostalCode : string.Empty,
                        MaritalStatus = cd.PatientRegistration != null ? cd.PatientRegistration.MaritalStatus : false,
                        DateOfBirth = cd.PatientRegistration != null ? cd.PatientRegistration.DateOfBirth : DateTime.MinValue,
                        CardNo = cd.PatientRegistration != null ? cd.PatientRegistration.CardNo : string.Empty,
                        TotalAmount = (cd.PatientRegistration != null ? cd.PatientRegistration.RegisterFee : 0) + 
                                    (cd.PatientRegistration != null ? cd.PatientRegistration.OtherFee : 0) + 
                                    (cd.UnitPrice * cd.Quantity) // 计算总费用
                    })
                    .ToListAsync();

                // 记录查询成功日志
                _logger.LogInformation("查询消费明细信息成功，共找到 {Count} 条记录", consumptionDetails.Count);

                var apiResult = new ApiResult<List<GetConsumptionDetailsDto>>();
                apiResult.success(consumptionDetails, "查询消费明细信息成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "查询消费明细信息时发生异常，患者姓名：{PatientName}，挂号单号：{RegisterNo}，药品名称：{DrugName}，病人挂号ID：{PatientRegistrationId}", 
                    patientName, registerNo, drugName, patientRegistrationId);
                return new ApiResult<List<GetConsumptionDetailsDto>> { msg = "查询消费明细信息时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 门诊结账
        /// </summary>
        /// <param name="checkoutDto">结账信息</param>
        /// <returns>结账结果</returns>
        public async Task<ApiResult<CheckoutResponseDto>> CheckoutAsync(CheckoutRequestDto checkoutDto)
        {
            try
            {
                // 记录结账开始日志
                _logger.LogInformation("开始门诊结账，挂号单号：{RegisterNo}，病人姓名：{PatientName}，总金额：{TotalAmount}，支付金额：{PaymentAmount}", 
                    checkoutDto.RegisterNo, checkoutDto.PatientName, checkoutDto.TotalAmount, checkoutDto.PaymentAmount);

                // 参数验证
                var validationResults = new List<ValidationResult>();
                var validationContext = new ValidationContext(checkoutDto);
                if (!Validator.TryValidateObject(checkoutDto, validationContext, validationResults, true))
                {
                    var errorMessage = string.Join("; ", validationResults.Select(v => v.ErrorMessage));
                    _logger.LogWarning("门诊结账失败：参数验证失败 - {ErrorMessage}", errorMessage);
                    return new ApiResult<CheckoutResponseDto> { msg = errorMessage };
                }

                // 验证支付金额是否足够
                if (checkoutDto.PaymentAmount < checkoutDto.TotalAmount)
                {
                    _logger.LogWarning("门诊结账失败：支付金额不足，支付金额：{PaymentAmount}，总金额：{TotalAmount}", 
                        checkoutDto.PaymentAmount, checkoutDto.TotalAmount);
                    return new ApiResult<CheckoutResponseDto> { msg = "支付金额不能少于总金额" };
                }

                // 检查是否已经结账
                var existingCheckout = await _context.Checkouts
                    .FirstOrDefaultAsync(c => c.RegisterNo == checkoutDto.RegisterNo && !c.IsDelete);

                if (existingCheckout != null)
                {
                    _logger.LogWarning("门诊结账失败：该挂号单号已结账，挂号单号：{RegisterNo}", checkoutDto.RegisterNo);
                    return new ApiResult<CheckoutResponseDto> { msg = "该挂号单号已结账，不能重复结账" };
                }

                // 生成发票号
                var invoiceNumber = GenerateInvoiceNumber();

                // 创建结账记录
                var checkout = new Checkout
                {
                    RegisterNo = checkoutDto.RegisterNo,
                    PatientName = checkoutDto.PatientName,
                    TotalAmount = checkoutDto.TotalAmount,
                    PaymentAmount = checkoutDto.PaymentAmount,
                    ChangeAmount = checkoutDto.ChangeAmount,
                    CheckoutTime = DateTime.Now,
                    InvoiceNumber = invoiceNumber,
                    PrintInvoice = checkoutDto.PrintInvoice,
                    OperatorId = checkoutDto.OperatorId,
                    Remarks = checkoutDto.Remarks,
                    CreateTime = DateTime.Now,
                    IsDelete = false
                };

                // 保存到数据库
                _context.Checkouts.Add(checkout);
                await _context.SaveChangesAsync();

                // 记录结账成功日志
                _logger.LogInformation("门诊结账成功，结账ID：{CheckoutId}，挂号单号：{RegisterNo}，发票号：{InvoiceNumber}", 
                    checkout.CheckoutId, checkout.RegisterNo, checkout.InvoiceNumber);

                // 构建响应DTO
                var responseDto = new CheckoutResponseDto
                {
                    CheckoutId = checkout.CheckoutId,
                    RegisterNo = checkout.RegisterNo,
                    PatientName = checkout.PatientName,
                    TotalAmount = checkout.TotalAmount,
                    PaymentAmount = checkout.PaymentAmount,
                    ChangeAmount = checkout.ChangeAmount,
                    CheckoutTime = checkout.CheckoutTime,
                    InvoiceNumber = checkout.InvoiceNumber,
                    PrintInvoice = checkout.PrintInvoice,
                    OperatorId = checkout.OperatorId,
                    Remarks = checkout.Remarks
                };

                var apiResult = new ApiResult<CheckoutResponseDto>();
                apiResult.success(responseDto, "门诊结账成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录异常日志
                _logger.LogError(ex, "门诊结账时发生异常，挂号单号：{RegisterNo}，病人姓名：{PatientName}", 
                    checkoutDto.RegisterNo, checkoutDto.PatientName);
                return new ApiResult<CheckoutResponseDto> { msg = "门诊结账时发生异常，请稍后重试" };
            }
        }

        /// <summary>
        /// 生成发票号
        /// </summary>
        /// <returns>发票号</returns>
        private string GenerateInvoiceNumber()
        {
            // 生成格式：INV + 年月日 + 6位随机数
            var dateStr = DateTime.Now.ToString("yyyyMMdd");
            var randomStr = new Random().Next(100000, 999999).ToString();
            return $"INV{dateStr}{randomStr}";
        }
    }
} 